#include "mscatteringlidarform.h"
#include "ui_mscatteringlidarform.h"
#include "../../protocol/gRPC/lidar.pb.h"
#include "../gloab/globalobserver.h"
#include "../gloab/mymessagebox.h"

#include <QMessageBox>
#include <QThread>
#include <QObject>
#include <QMutexLocker>

MScatteringLidarForm::MScatteringLidarForm(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::MScatteringLidarForm)
    , m_client(nullptr)
    , m_channel(nullptr)
{
    ui->setupUi(this);
    connect(this, &MScatteringLidarForm::Sig_sendLidarClient, GlobalObserver::getInstance(), &GlobalObserver::Sig_lidarGetClint);
    formInit();
}

MScatteringLidarForm::~MScatteringLidarForm()
{
    delete ui;
}

void MScatteringLidarForm::formInit()
{
    //登录按钮，创造channel并初始化存根
    connect(ui->btn_loginLogout, &QPushButton::clicked, this, [=](){
        if(ui->btn_loginLogout->text() == "登录"){
            QString str = ui->edit_ip->text();
            str += ":" + ui->edit_port->text();
            qDebug()<<str.toUtf8().toStdString();
            m_channel = grpc::CreateChannel(str.toUtf8().toStdString(), grpc::InsecureChannelCredentials());
            if(m_channel){
                m_client.reset(new LidarClient(m_channel, this));
                //数据反演时需要调用grpc获取信息，因此将clint暴露给数据反演页面
                emit Sig_sendLidarClient(m_client);
                //连接lidarClient调用完成的信号和自己的槽，使用Qt::QueuedConnection，保证在不同线程能够使用
                //注意必须在clint连接设备成功后才能进行连接信号和槽
                connect(m_client.data(), &LidarClient::Sig_GetPMTState, this, &MScatteringLidarForm::Slot_resGetPMTState, Qt::QueuedConnection);
                connect(m_client.data(), &LidarClient::Sig_StartAcquire, this, &MScatteringLidarForm::Slot_resStartAcquire, Qt::QueuedConnection);
                connect(m_client.data(), &LidarClient::Sig_GetNextComputeData, this, &MScatteringLidarForm::Slot_resGetNextComputeData, Qt::QueuedConnection);
                connect(m_client.data(), &LidarClient::Sig_GetNextData, this, &MScatteringLidarForm::Slot_resGetNextData, Qt::QueuedConnection);
                /*
                    补充登录代码，通过登录代码判断是否登录成功，修改登录的按钮
                */
                ui->btn_loginLogout->setText("退出") ;
                //以下为测试代码
                connect(ui->beginQuerydata, &QPushButton::clicked, this, &MScatteringLidarForm::test_beginQueryData);
                connect(ui->computer, &QPushButton::clicked, this, &MScatteringLidarForm::test_computer);
                connect(ui->getNextComputerData, &QPushButton::clicked, this, &MScatteringLidarForm::test_getNextComputerData);
                connect(ui->setLaser, &QPushButton::clicked, this, &MScatteringLidarForm::test_setLaser);
                connect(ui->getNextData, &QPushButton::clicked, this, &MScatteringLidarForm::test_getNextData);
                connect(ui->moveToAngle, &QPushButton::clicked, this, &MScatteringLidarForm::test_moveToAngle);
            }


        }
        else{
            disconnect(m_client.data(), 0, 0, 0);
            m_channel = nullptr;
            ui->btn_loginLogout->setText("登录");
        }

    });

    //开始采集按钮
    connect(ui->btn_startStopAcquire, &QPushButton::clicked, this, [=](){
        if(!m_client){
            MyMessageBox msgBox(this, MsgBoxType_Info, "雷达未登录");
            msgBox.exec();
            return;
        }

        if(ui->btn_startStopAcquire->text() == "开始采集"){
            //m_client->getPMTState(::lidar::GUID());
            std::thread a([this](){

                ::lidar::AcquireParamsPackage acquireParamsPackage;
                acquireParamsPackage.mutable_id()->CopyFrom(m_guid);
                lidar::OperationParameters* operationParameters = new lidar::OperationParameters;
                //operationParameters
                operationParameters->set_detectmode(ui->cbx_detectMode->currentIndex());
                operationParameters->set_duration(ui->cbx_duration->currentText().toInt());
                operationParameters->set_resolution(ui->cbx_resolution->currentText().toInt());

                acquireParamsPackage.mutable_para()->CopyFrom(*operationParameters);
                QMutexLocker<QMutex> locker(&m_mutex);
                m_client->startAcquire(acquireParamsPackage);
            });
            a.detach();
            ui->btn_startStopAcquire->setText("停止采集");
        }
        else{
            std::thread a([this](){
                QMutexLocker<QMutex> locker(&m_mutex);
                m_client->stopAcquire(m_guid);
            });
            ui->btn_startStopAcquire->setText("开始采集");
        }
    });
}

void MScatteringLidarForm::test_computer()
{
    lidar::ComputeParamsPackage computeParamsPackage;
    QDateTime currentDateTime = QDateTime::currentDateTime().addSecs(-300);
    google::protobuf::Timestamp startTime, endTime;

    qint64 seconds = currentDateTime.toSecsSinceEpoch();
    qint64 msecs = currentDateTime.toMSecsSinceEpoch() % 1000;
    startTime.set_seconds(seconds);
    startTime.set_nanos(msecs * 1000000);

    currentDateTime = QDateTime::currentDateTime();
    seconds = currentDateTime.toSecsSinceEpoch();
    msecs = currentDateTime.toMSecsSinceEpoch() % 1000;
    endTime.set_seconds(seconds);
    endTime.set_nanos(msecs * 1000000);

    lidar::AlgrithmParams algrithmParams;

    computeParamsPackage.mutable_methodparams()->CopyFrom(algrithmParams);
    computeParamsPackage.mutable_dtfrom()->CopyFrom(startTime);
    computeParamsPackage.mutable_dtto()->CopyFrom(endTime);
    computeParamsPackage.mutable_id()->CopyFrom(m_guid);

    m_client->compute(computeParamsPackage);

    QMutexLocker<QMutex> locker(&m_mutex);
}

void MScatteringLidarForm::test_getNextComputerData()
{
    lidar::AlgrithmParamsPackage algrithmParamsPackage;
    algrithmParamsPackage.mutable_id()->CopyFrom(m_guid);
    algrithmParamsPackage.set_requestedmethods(0x0400);

    QSharedPointer<lidar::ComputedResult> response = m_client->getNextComputerData(algrithmParamsPackage);
    const std::string& dataElement = response->data(0);
    qDebug() << " size:" << dataElement.size();
}

void MScatteringLidarForm::test_setLaser()
{
    lidar::LaserLD laserLD;
    laserLD.mutable_id()->CopyFrom(m_guid);
    int strength = 0;
    if(ui->cbx_setLaser->currentIndex() == 0){
        strength = 650;
    }else if(ui->cbx_setLaser->currentIndex() == 1){
        strength = 700;
    }else{
        strength = 800;
    }
    laserLD.set_syscurrent(strength);
    laserLD.set_en(true);
    m_client->setLaser(laserLD);
}

void MScatteringLidarForm::test_beginQueryData()
{
    lidar::RawParamsPackage rawParamsPackage;
    rawParamsPackage.mutable_id()->CopyFrom(m_guid);
    QDateTime currentDateTime = QDateTime::currentDateTime().addSecs(-300);
    google::protobuf::Timestamp startTime, endTime;

    qint64 seconds = currentDateTime.toSecsSinceEpoch();
    qint64 msecs = currentDateTime.toMSecsSinceEpoch() % 1000;
    startTime.set_seconds(seconds);
    startTime.set_nanos(msecs * 1000000);

    currentDateTime = QDateTime::currentDateTime();
    seconds = currentDateTime.toSecsSinceEpoch();
    msecs = currentDateTime.toMSecsSinceEpoch() % 1000;
    endTime.set_seconds(seconds);
    endTime.set_nanos(msecs * 1000000);

    rawParamsPackage.mutable_dtfrom()->CopyFrom(startTime);
    rawParamsPackage.mutable_dtto()->CopyFrom(endTime);

    m_client->beginQueryData(rawParamsPackage);

}

void MScatteringLidarForm::test_getNextData()
{
    QSharedPointer<lidar::LidarRawData> lidarRawData = m_client->getNextData(m_guid);

    qDebug()<<"温度: "<<lidarRawData->temperature()<<"湿度: "<<lidarRawData->humidity()<<"压力: "<<lidarRawData->atompressure();
}

void MScatteringLidarForm::test_moveToAngle()
{
    lidar::RocMovePara rocMovePara;
    rocMovePara.mutable_id()->CopyFrom(m_guid);
    rocMovePara.set_dir(true);
    rocMovePara.set_angle(ui->edit_movetoAngle->text().toInt());

    m_client->setRocMoveToAngle(rocMovePara);
}


void MScatteringLidarForm::Slot_resGetPMTState(const QSharedPointer<lidar::RuntimeParamsPackage> response)
{


}

void MScatteringLidarForm::Slot_resStartAcquire(const QSharedPointer<lidar::XError>)
{

}

void MScatteringLidarForm::Slot_resGetNextComputeData(const QSharedPointer<lidar::ComputedResult>)
{

}

void MScatteringLidarForm::Slot_resGetNextData(const QSharedPointer<lidar::LidarRawData>)
{

}
